package com.java.Map;

import java.util.*;
import java.util.function.BiConsumer;

/**
 * 双列集合Map遍历：其子类HashMap(LinkedHashMap)、TreeMap均适用
 */
public class MapTraverse {
    // values遍历
    public static <K, V> void mapValues(Map<K, V> map) {
        Collection<V> values = map.values(); // values：以集合形式获取所有值
        for (V value : values) {
            System.out.print(value + " ");
        }
        System.out.println();
    }
    
    // keySet遍历
    public static <K, V> void mapKeySet(Map<K, V> map) {
        Set<K> set = map.keySet(); // keySet：以Set形式获取所有键
        for (K key : set) {
            V value = map.get(key); // get：获取集合内一个指定键的值
            System.out.print(key + ":" + value + " ");
        }
        System.out.println();
    }
    
    // entrySet遍历
    public static <K, V> void mapEntrySet(Map<K, V> map) {
        Set<Map.Entry<K, V>> set = map.entrySet(); // entrySet：以Set形式获取键值对
        for (Map.Entry<K, V> me : set) {
            K key = me.getKey(); // getKey：获取键
            V value = me.getValue(); // getValue：获取值
            System.out.print(key + ":" + value + " ");
        }
        System.out.println();
    }
    
    // forEach遍历：底层就是entrySet增强for循环遍历
    public static <K, V> void mapForEach(Map<K, V> map) {
        map.forEach(new BiConsumer<K, V>() {
            @Override
            public void accept(K key, V value) {
                System.out.print(key + ":" + value + " ");
            }
        });
        System.out.println();
    }
    
    // lambda简化forEach遍历
    public static <K, V> void mapForEachLambda(Map<K, V> map) {
        map.forEach((K key, V value) -> System.out.print(key + ":" + value + " "));
        System.out.println();
    }
    
    public static void main(String[] args) {
        HashMap hashMap = newInstance(new HashMap<>());
        LinkedHashMap linkedHashMap = newInstance(new LinkedHashMap<>());
        TreeMap treeMap = newInstance(new TreeMap<>());
        Properties properties = newInstance(new Properties());
        
        // values遍历
        mapValues(hashMap); // C B A
        mapValues(linkedHashMap); // A C B
        mapValues(treeMap); // C B A
        mapValues(properties); // A B C
        
        // keySet遍历
        mapKeySet(hashMap); // 1:C 2:B 3:A
        mapKeySet(linkedHashMap); // 3:A 1:C 2:B
        mapKeySet(treeMap); // 1:C 2:B 3:A
        mapKeySet(properties); // 3:A 2:B 1:C
        
        // entrySet遍历
        mapEntrySet(hashMap); // 1:C 2:B 3:A
        mapEntrySet(linkedHashMap); // 3:A 1:C 2:B
        mapEntrySet(treeMap); // 1:C 2:B 3:A
        mapEntrySet(properties); // 3:A 2:B 1:C
        
        // forEach遍历
        mapForEach(hashMap); // 1:C 2:B 3:A
        mapForEach(linkedHashMap); // 3:A 1:C 2:B
        mapForEach(treeMap); // 1:C 2:B 3:A
        mapForEach(properties); // 3:A 2:B 1:C
        
        // lambda简化forEach遍历
        mapForEachLambda(hashMap); // 1:C 2:B 3:A
        mapForEachLambda(linkedHashMap); // 3:A 1:C 2:B
        mapForEachLambda(treeMap); // 1:C 2:B 3:A
        mapForEachLambda(properties); // 3:A 2:B 1:C
    }
    
    public static <T extends Map> T newInstance(T map) {
        map.put(3, "A");
        map.put(1, "C");
        map.put(2, "B");
        return map;
    }
}
